package it.unicam.cs.cosy.bioshape.core.components.services;

import java.io.Serializable;

import javax.vecmath.Tuple3d;

/**
 * Defines a generic {@code Service} running on a {@code LocalCoordinator}. It
 * defines the entry method for the application of its features. Implementations
 * should provide specific additional information if required.
 * 
 * @author Federico Buti
 */
public interface Service extends Serializable {

	/**
	 * Defines the entry point to the {@code Service} behaviour. Any
	 * implementing class must override this method with specific behaviour. The
	 * fist {@code String} parameter <i>MUST</i> be a constant defined inside
	 * the class and identifying the specific task which the service must
	 * execute. A constant must be defined for each task executed by the
	 * {@code Service}.
	 * 
	 * @param constant
	 *            Unique constant for a specific task to execute.
	 * @param center
	 *            Reference point of the entity in space.
	 * @param radius
	 *            Perception radius, useful with services which can be
	 *            perceived.
	 * @param data
	 *            Data given as input to the Service. Must be the current one
	 *            for the task to execute
	 * @return The outcomes of the task stored inside the same array passed as
	 *         input //TODO mettere il riferimento a qualche servizio creato per
	 *         far capire meglio...sicuramente quello del groupedentity!
	 */
	Object executeTask(int constant, Tuple3d center, double radius,
			Object[] data);

	/**
	 * Identify a {@code Services} which can be perceived by an entity. By
	 * "perceiving" we mean that the {@code ShapedEntity} can sense the
	 * information provided by the service to the environment in which the
	 * {@code ShapedEntity} is located.
	 * 
	 * @return {@code true} if the {@code Service} information can be sensed by
	 *         the {@code Entity}, {@code false} otherwise
	 */
	boolean isPerceptible();

	/**
	 * Returns the data perceived by the requesting entity. This method must be
	 * carefully implemented as it highly influences the way in which the
	 * {@code Service} operates in the simulation. It can be left empty if the
	 * {@code Service} is not perceived, i.e. if the {@code #isPerceptible()}
	 * method returns {@code false}.
	 * 
	 * @return The information which an {@code Entity} can perceive about this
	 *         {@code Service}
	 * 
	 * @see #isPerceptible()
	 */
	Object getPerceptibleData();
}